package com.hen.web.henweb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hen.web.henweb.common.Pageable;
import com.hen.web.henweb.exception.BusinessException;
import com.hen.web.henweb.mapper.ArticleMapper;
import com.hen.web.henweb.model.enumeration.ArticleStatusEnum;
import com.hen.web.henweb.model.po.Article;
import com.hen.web.henweb.model.po.User;
import com.hen.web.henweb.model.vo.ArticleVO;
import com.hen.web.henweb.service.ArticleService;
import com.hen.web.henweb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 狠穿
 * @version 1.0.0
 * @date 2023/4/30
 * @function 文章业务层实现
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserService userService;

    /**
     * 发表文章
     * @param title 文章标题
     * @param authorId 发布者ID
     * @param content 文章内容
     * @return 发布成功的文章数量
     */
    @Override
    public int publishArticle(@NotBlank(message = "文章标题不可为空") String title,
                              @NotBlank(message = "发布者不可为空") String authorId,
                              @NotBlank(message = "文章内容不可为空") String content) {
        Article article = new Article();
        if(containSensitiveWords(title)){
            throw new BusinessException("文章标题不可包含敏感字眼!");
        }
        article.setTitle(title);
        if(containSensitiveWords(content)){
            throw new BusinessException("文章内容不可包含敏感字眼!");
        }
        article.setContent(content);
        article.setAuthorId(authorId);
        article.setSendTime(DateUtil.now());
        return articleMapper.insert(article);
    }

    /**
     * 删除文章
     * @param id 待删除的文章ID
     * @return 删除成功的条数
     */
    @Override
    public int deleteArticle(@NotBlank(message = "文章ID不可为空") String id) {
        return articleMapper.deleteById(id);
    }

    /**
     * 修改文章
     * @param id 待修改的文章ID
     * @param title 标题
     * @param content 内容
     * @return 修改成功的文章数量
     */
    @Override
    public int updateArticle(@NotBlank(message = "文章ID不可为空") String id,
                             @NotBlank(message = "文章标题不可为空") String title,
                             @NotBlank(message = "文章内容不可为空") String content) {
        if(containSensitiveWords(title)){
            throw new BusinessException("文章标题不可包含敏感字眼!");
        }
        if(containSensitiveWords(content)){
            throw new BusinessException("文章内容不可包含敏感字眼!");
        }
        Article article = new Article();
        article.setId(id);
        article.setTitle(title);
        article.setContent(content);
        return articleMapper.updateById(article);
    }

    /**
     * 判断字符串是否包含敏感字眼
     * @param str 待校验的字符串
     * @return boolean
     */
    private boolean containSensitiveWords(String str) {
        if(StrUtil.isBlank(str)){
            return false;
        }
        //TODO:敏感词需要管理员自行定义，此处先采用模拟方式进行，后续开发敏感词定义接口
        return str.contains("操");
    }

    /**
     * 查询文章列表
     * @param pageable 分页对象
     * @return List<Article>
     */
    @Override
    public List<ArticleVO> listArticles(Pageable pageable) {
        if(pageable == null){
            throw new BusinessException("分页信息不可为空!");
        }
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getStatus, ArticleStatusEnum.SHOW);
        queryWrapper.orderByDesc(Article::getWeight,Article::getSendTime);
        Page<Article> articlePage = articleMapper.selectPage(pageable.toPage(), queryWrapper);
        return articlePage.getRecords().stream().map(article -> {
            ArticleVO articleVO = BeanUtil.copyProperties(article, ArticleVO.class);
            //TODO 根据userID查询用户信息
            User user = userService.findUserById(article.getAuthorId());
            articleVO.setAvatar(user.getAvatar());
            articleVO.setNickName(user.getNickName());
            return articleVO;
        }).collect(Collectors.toList());
    }

    /**
     * 判断文章是否存在
     * @param articleId 文章ID
     * @return Boolean
     */
    @Override
    public Boolean existArticle(String articleId) {
        if(StrUtil.isBlank(articleId)){
            throw new BusinessException("文章ID不可为空");
        }
        return getArticleById(articleId)==null?false:true;
    }

    /**
     * 根据ID查询文章
     * @param articleId
     * @return ArticleVO
     */
    @Override
    public Article getArticleById(String articleId) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getId,articleId);
        return articleMapper.selectOne(queryWrapper);
    }

    /**
     * 阅读文章
     * @param articleId 文章ID
     * @param userId 用户ID
     * @return int
     */
    @Override
    public int readArticle(String articleId, String userId) {
        Article article = getArticleById(articleId);
        if(article == null){
            throw new BusinessException(StrUtil.format("不存在编号为{}的文章",articleId));
        }
        article.setReadCount(article.getReadCount()+1);
        //TODO 插入文章阅读记录表
        return articleMapper.updateById(article);
    }

    /**
     * 点赞文章
     * @param articleId 文章ID
     * @param userId 点赞用户ID
     * @return int
     */
    @Override
    public int praiseArticle(String articleId, String userId) {
        Article article = getArticleById(articleId);
        if(article == null){
            throw new BusinessException(StrUtil.format("不存在编号为{}的文章",articleId));
        }
        //TODO 插入文章点赞记录表
        article.setPraiseCount(article.getPraiseCount()+1);
        return articleMapper.updateById(article);
    }

    /**
     * 收藏文章
     *@param articleId 文章ID
     *@param userId 收藏用户ID
     *@return int
     */
    @Override
    public int collectArticle(String articleId, String userId) {
        Article article = getArticleById(articleId);
        if(article == null){
            throw new BusinessException(StrUtil.format("不存在编号为{}的文章",articleId));
        }
        //收藏数量+1
        article.setCollectCount(article.getCollectCount()+1);
        //TODO 插入文章收藏记录表
        return articleMapper.updateById(article);
    }
}
